home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / MacStarter (THINK C 5.0⁄6.0) / inputBoxes.c < prev    next >
Text File  |  1994-01-25  |  9KB  |  326 lines

  1. /* This file defines some functions for using Mac dialog boxes.
  2.    See the README file that should be in the same folder with this file.
  3. */
  4.  
  5. #include "inputBoxes.h"  // also includes stdio.h
  6. #include "ctype.h"
  7. #include "stdlib.h"
  8. #include "errno.h"
  9.  
  10. void TellUser(const Str255 message) {
  11.    ParamText(message,"\p","\p","\p");
  12.    NoteAlert(129,0L);
  13. }
  14.  
  15. short AskUser(const Str255 question, short* answeredYes) {
  16.    short temp;
  17.    ParamText(question,"\p","\p","\p");
  18.    temp = Alert(130,0L);
  19.    *answeredYes = (temp == ok);
  20.    return (temp != cancel);
  21. }
  22.  
  23. void AskUserWithoutCancel(const Str255 question, short* answeredYes) {
  24.    short temp;
  25.    ParamText(question,"\p","\p","\p");
  26.    temp = Alert(131,0L);
  27.    *answeredYes = (temp == ok);
  28. }
  29.  
  30. static DialogRecord dlgRec;
  31. static DialogPtr dlg;
  32. static short maxStringLength;
  33. static long maxLong, minLong;
  34. static double maxDouble, minDouble;
  35. static long inputLong;
  36. static double inputDouble;
  37. static unsigned char inputStr[257];
  38. static const unsigned char *thePrompt;
  39. static Handle inputItem;
  40. static ControlHandle okBttn, cancelBttn;
  41. enum {
  42.    getStr,
  43.    getLong,
  44.    getDouble,
  45.    getWord
  46. } dlgType;
  47.  
  48. short RunDialog(void);
  49. pascal Boolean dlgFilter(DialogPtr dlg, EventRecord *theEvent, short *item);
  50. short CheckInput(void);
  51.  
  52.  
  53. short InputString(const Str255 prompt, Str255 str, const short maxLength) {
  54.    short temp;
  55.    short i;
  56.    maxStringLength = ( maxLength > 0 && maxLength < 256) ? maxLength : 255;
  57.    if (maxStringLength <= 32)
  58.       dlg = GetNewDialog(132,&dlgRec,(WindowPtr) -1);
  59.    else
  60.       dlg = GetNewDialog(133,&dlgRec,(WindowPtr) -1);
  61.    dlgType = getStr;
  62.    thePrompt = prompt;
  63.    temp = RunDialog();
  64.    if (temp)
  65.       for (i=0;i<=inputStr[0];i++)
  66.          str[i] = inputStr[i];
  67.    return temp;
  68. }
  69.  
  70. short InputWord(const Str255 prompt, Str255 str, const short maxLength) {
  71.    short temp;
  72.    short i;
  73.    maxStringLength = ( maxLength > 0 && maxLength < 256) ? maxLength : 255;
  74.    if (maxStringLength <= 32)
  75.       dlg = GetNewDialog(132,&dlgRec,(WindowPtr) -1);
  76.    else
  77.       dlg = GetNewDialog(133,&dlgRec,(WindowPtr) -1);
  78.    dlgType = getWord;
  79.    thePrompt = prompt;
  80.    temp = RunDialog();
  81.    if (temp)
  82.       for (i=0;i<=inputStr[0];i++)
  83.          str[i] = inputStr[i];
  84.    return temp;
  85. }
  86.  
  87. short InputLongInt(const Str255 prompt, long* n, const long min, const long max) {
  88.    short temp;
  89.    maxLong = max;
  90.    minLong = min;
  91.    dlg = GetNewDialog(132,&dlgRec,(WindowPtr) -1);
  92.    dlgType = getLong;
  93.    thePrompt = prompt;
  94.    temp = RunDialog();
  95.    if (temp)
  96.       *n = inputLong;
  97.    return temp;
  98. }
  99.  
  100. short InputDouble(const Str255 prompt, double* x, const double min, const double max) {
  101.    short temp;
  102.    maxDouble = max;
  103.    minDouble = min;
  104.    dlg = GetNewDialog(132,&dlgRec,(WindowPtr) -1);
  105.    dlgType = getDouble;
  106.    thePrompt = prompt;
  107.    temp = RunDialog();
  108.    if (temp)
  109.       *x = inputDouble;
  110.    return temp;
  111. }
  112.  
  113. short RunDialog() {
  114.    short hit;
  115.    short itemType;
  116.    Rect box;
  117.    GrafPtr savePort;
  118.    GetPort(&savePort);
  119.    ParamText(thePrompt,"\p","\p","\p");
  120.    SelectWindow(dlg);
  121.    SetPort(dlg);
  122.    GetDItem(dlg, 2, &itemType, (Handle*)&cancelBttn, &box);
  123.    GetDItem(dlg, 1, &itemType, (Handle*)&okBttn, &box);
  124.    InsetRect(&box,-4,-4);
  125.    PenSize(3,3);
  126.    FrameRoundRect(&box,16,16);
  127.    GetDItem(dlg, 4, &itemType, &inputItem, &box);
  128.    for (;;) {
  129.       ModalDialog(&dlgFilter,&hit);
  130.       if (hit == ok) {
  131.          if (CheckInput())
  132.             break;
  133.       }
  134.       else if (hit == cancel) {
  135.          break;
  136.       }
  137.    };
  138.    DisposeDialog(dlg);
  139.    return (hit == ok);
  140. }
  141.  
  142. pascal Boolean dlgFilter(DialogPtr dlg, EventRecord *theEvent, short *item) {
  143.    Boolean eventOK;
  144.    long junk;
  145.    short ch;
  146.    if ( (theEvent->what == keyDown || theEvent->what == autoKey)
  147.                &&  !(theEvent->modifiers & cmdKey) ) {
  148.       ch = theEvent->message & 0xFF;
  149.       if ( ch == 13 || ch == 3 ) {
  150.          HiliteControl(okBttn,1);
  151.          Delay(10,&junk);
  152.          HiliteControl(okBttn,0);
  153.          *item = ok;
  154.          return true;
  155.       }
  156.       else if ( ch == 27 ) {
  157.          HiliteControl(cancelBttn,1);
  158.          Delay(10,&junk);
  159.          HiliteControl(cancelBttn,0);
  160.          *item = cancel;
  161.          return true;
  162.       }
  163.       else if ( (ch <= 31 && ch >= 28) || (ch == 8) ) {
  164.          return false;
  165.       }
  166.       else {
  167.          switch ( dlgType ) {
  168.          case getWord:
  169.             eventOK = isalpha(ch);
  170.             break;
  171.          case getStr:
  172.             eventOK = (ch > 31);
  173.             break;
  174.          case getLong:
  175.             eventOK = isdigit(ch) || (ch == '-' && (minLong < 0 || minLong >= maxLong));
  176.             break;
  177.          case getDouble:
  178.             eventOK = isdigit(ch) || (ch == '.') || (ch == 'e')
  179.                          || (ch == 'E') || (ch == '+') || (ch == '-');
  180.         };
  181.         if ( !eventOK ) {
  182.             *item = 0;
  183.             SysBeep(1);
  184.         };
  185.         return !eventOK;
  186.       }
  187.    }
  188.    else
  189.       return false;
  190. }
  191.  
  192. short CheckInput(void) {
  193.    short dataOK;
  194.    char* endptr;
  195.    char message[256];
  196.    GetIText(inputItem,inputStr);
  197.    switch (dlgType) {
  198.       case getStr:
  199.          dataOK = (inputStr[0] > 0) && (inputStr[0] <= maxStringLength);
  200.          if (!dataOK) {
  201.             sprintf(message,
  202.                          "Please input a string of between 1 and %i characters.",
  203.                          maxStringLength);
  204.          };
  205.          break;
  206.       case getWord:
  207.          dataOK = (inputStr[0] > 0) && (inputStr[0] <= maxStringLength);
  208.          if (!dataOK) {
  209.             sprintf(message,
  210.                          "Please input a string of between 1 and %i letters.",
  211.                          maxStringLength);
  212.          };
  213.          break;
  214.       case getLong:
  215.          if (inputStr[0] == 0)
  216.             dataOK = 0;
  217.          inputStr[inputStr[0]+1] = 0;
  218.          errno = 0;
  219.          inputLong = strtol((char*)inputStr+1,&endptr,10);
  220.          dataOK = (errno == 0)
  221.                     && (*endptr == 0)
  222.                     && ((minLong >= maxLong) 
  223.                             || (inputLong >= minLong && inputLong <= maxLong));
  224.          if (!dataOK) {
  225.             if (maxLong <= minLong)
  226.                sprintf(message,"Please input a legal integer.");
  227.             else
  228.                sprintf(message,
  229.                   "Please input a legal integer in the range from %li to %li.",
  230.                   minLong, maxLong);
  231.          };
  232.          break;
  233.       case getDouble:
  234.           if (inputStr[0] == 0)
  235.             dataOK = 0;
  236.          inputStr[inputStr[0]+1] = 0;
  237.          errno = 0;
  238.          inputDouble = strtod((char*)inputStr+1,&endptr);
  239.          dataOK = (errno == 0)
  240.                     && (*endptr == 0)
  241.                     && ((minDouble >= maxDouble) 
  242.                             || (inputDouble >= minDouble && inputDouble <= maxDouble));
  243.          if (!dataOK) {
  244.             if (maxDouble <= minDouble)
  245.                sprintf(message,"Please input a legal number.");
  246.             else
  247.                sprintf(message,
  248.                   "Please input a legal number in the range from %g to %g.",
  249.                   minDouble, maxDouble);
  250.          };
  251.   };
  252.    if (!dataOK) {
  253.       CtoPstr(message);
  254.       ParamText((unsigned char*)message,"\p","\p","\p");
  255.       StopAlert(135,0L);
  256.       ParamText(thePrompt,"\p","\p","\p");
  257.       SelIText(dlg,4,0,32000);
  258.    };
  259.    return dataOK;
  260. }
  261.  
  262. FILE* OpenNewFile(const Str255 prompt, Str255 fileName) {
  263.    Point where;
  264.    SFReply reply;
  265.    FILE *file;
  266.    short i;
  267.    OSErr err;
  268.    where.h = 20;
  269.    where.v = 60;
  270.    SFPutFile(where, prompt, fileName, 0, &reply);
  271.    if (reply.good) {
  272.        err = Create(reply.fName,reply.vRefNum,'ttxt','TEXT');
  273.        if (err == dupFNErr) {
  274.           err = FSDelete(reply.fName, reply.vRefNum);
  275.           if (err != noErr) {
  276.              TellUser("\pSorry, unable to delete existing file of the same name.");
  277.              return 0;
  278.           };
  279.           err = Create(reply.fName,reply.vRefNum,'ttxt','TEXT');
  280.        };
  281.        if (err == wPrErr || err == vLckdErr) {
  282.           TellUser("\pSorry, unable to write to that disk; it is locked or write protected.");
  283.           return 0;
  284.        };
  285.        if (err != noErr) {
  286.           TellUser("\pSorry, an error occured while trying to create the new file.");
  287.           return 0;
  288.        };
  289.        if (fileName)
  290.           for (i=0; i<=reply.fName[0]; i++)
  291.              fileName[i] = reply.fName[i];
  292.        SetVol(0,reply.vRefNum);
  293.        PtoCstr(reply.fName);
  294.        file = fopen((char*)reply.fName,"w");
  295.        if (!file)
  296.           TellUser("\pSorry, an error occured while trying to open the new file.");
  297.        return file;
  298.    }
  299.    else
  300.       return 0;
  301. }
  302.  
  303. FILE* OpenOldFile(Str255 fileName) {
  304.    Point where;
  305.    SFTypeList typeList;
  306.    SFReply reply;
  307.    FILE *file;
  308.    short i;
  309.    typeList[0] = 'TEXT';
  310.    where.h = 20;
  311.    where.v = 60;
  312.    SFGetFile(where, 0, 0, 1, typeList, 0, &reply);
  313.    if (reply.good) {
  314.        if (fileName)
  315.           for (i=0; i<=reply.fName[0]; i++)
  316.              fileName[i] = reply.fName[i];
  317.        SetVol(0,reply.vRefNum);
  318.        PtoCstr(reply.fName);
  319.        file = fopen((char*)reply.fName,"r");
  320.        if (!file)
  321.           TellUser("\pSorry, an error occured while trying to open that file for reading.");
  322.        return file;
  323.    }
  324.    else
  325.       return 0;
  326. }